//-----------------------------------------------------------------------------
// CreateSubscriber
//
// Copyright (c) MetaSwitch 2006 - 2008
//
// Author: Alex Davies
//
// Sample application demonstrating the SOAP Sh interface to the MetaView
// Server.  This application sends in an Sh-Update request to create a new
// subscriber, and then sends an Sh-Pull request to fetch the new subscriber's
// alarm state to ensure it was correctly configured.  It uses Apache Axis and
// the "typed" WSDL file.  It also demonstrates how you can connect to a
// MetaView Server other than the one specified in the WSDL file.
//
// See the readme file for more information.
//-----------------------------------------------------------------------------

import javax.xml.rpc.holders.*;

import com.MetaSwitch.EMS.SOAP.*;
import com.MetaSwitch.EMS.SOAP.holders.*;

public class CreateSubscriber
{
  private final static String USAGE = "Usage: CreateSubscriber [-ems " +
                                      "<MetaView Server name>] -dn <Directory " +
                                      "number> -metaswitch <MetaSwitch " +
                                      "name> (-businessgroup <Business " +
                                      "Group name> | [-subscribergroup " +
                                      "<Subscriber Group>] [-profile " +
                                      "<Persistent Profile>] [-username " +
                                      "<SIP user name>] -domain <SIP domain " +
                                      "name> [-password <SIP password>]";
  private static ShTypedUtilities utilities = new ShTypedUtilities();

  public static void main(String[] args)
  {
    StringHolder emsAddressHolder = new StringHolder();
    StringHolder dNHolder = new StringHolder();

    IntHolder resultCodeHolder = new IntHolder();
    TExtendedResultHolder extendedResultHolder = new TExtendedResultHolder();
    TUserDataHolder userDataHolder = new TUserDataHolder();

    try
    {
      //-----------------------------------------------------------------------
      // Extract information from the command line arguments.
      //-----------------------------------------------------------------------
      SubscriberInfo subscriberInfo = getParameters(args,
                                                    emsAddressHolder,
                                                    dNHolder);

      //-----------------------------------------------------------------------
      // Prepare to connect to the Sh service.
      //-----------------------------------------------------------------------
      ShServiceLocator locator = new ShServiceLocator();
      if (emsAddressHolder.value != null)
      {
        locator.setShServiceEndpointAddress(emsAddressHolder.value);
      }

      Sh shInstance = locator.getShService();

      //-----------------------------------------------------------------------
      // Put together the user data and set the required fields.  In addition
      // to the parameters provided, set:
      // -  CallAgentSignalingType to "SIP"
      // -  NumberStatus to "Normal"
      // -  Locale to "English (US)"
      // There are constants within the auto-generated classes that would be
      // more efficient to use; however, the fromString methods are used here
      // for readability.
      //-----------------------------------------------------------------------
      TMeta_Subscriber_BaseInformation baseInformation =
                                        new TMeta_Subscriber_BaseInformation();
      baseInformation.setCallAgentSignalingType(
                        TMeta_Subscriber_BaseInformation_CallAgentSignalingType
                        .fromString("SIP"));
      baseInformation.setNumberStatus(
           TMeta_Subscriber_BaseInformation_NumberStatus.fromString("Normal"));

      if (subscriberInfo.businessGroupName.toString() == null)
      {
        baseInformation.setLocale(
           TMeta_Subscriber_BaseInformation_Locale.fromString("English (US)"));
        baseInformation.setSubscriberGroup(
                                    subscriberInfo.subscriberGroup.toString());
      }
      else
      {
        TSwitchableDefaultString subGp;
        String requestedSubscriberGroup =
                                     subscriberInfo.subscriberGroup.toString();

        if (requestedSubscriberGroup == null)
        {
          subGp = new TSwitchableDefaultString(TTrueFalse.True, null, null);
        }
        else
        {
          subGp = new TSwitchableDefaultString(TTrueFalse.False,
                                               requestedSubscriberGroup,
                                               null);
        }

        baseInformation.setSubscriberGroupBusLine(subGp);
      }

      baseInformation.setMetaSwitchName(
                                     subscriberInfo.metaSwitchName.toString());
      baseInformation.setBusinessGroupName(
                                  subscriberInfo.businessGroupName.toString());
      baseInformation.setPersistentProfile(
                                  subscriberInfo.persistentProfile.toString());
      baseInformation.setSIPDomainName(
                                      subscriberInfo.sipDomainName.toString());

      if (subscriberInfo.sipUserName.toString() == null)
      {
        baseInformation.setUseDNForIdentification(TTrueFalse.True);
      }
      else
      {
        baseInformation.setUseDNForIdentification(TTrueFalse.False);
        baseInformation.setSIPUserName(subscriberInfo.sipUserName.toString());
      }

      if (subscriberInfo.sipPassword.toString() == null)
      {
        baseInformation.setSIPAuthenticationRequired(TTrueFalse.False);
      }
      else
      {
        baseInformation.setSIPAuthenticationRequired(TTrueFalse.True);
        baseInformation.setNewSIPPassword(
                                        subscriberInfo.sipPassword.toString());
        baseInformation.setConfirmNewSIPPassword(
                                        subscriberInfo.sipPassword.toString());
      }

      TMetaSwitchData metaSwitchData = new TMetaSwitchData();
      metaSwitchData.setMeta_Subscriber_BaseInformation(baseInformation);

      TServiceData serviceData = new TServiceData();
      serviceData.setMetaSwitchData(metaSwitchData);

      TUserData userData = new TUserData
                           (
                             new TShData
                             (
                               new TTransparentData
                               (
                                 "Meta_Subscriber_BaseInformation",
                                 0,
                                 serviceData
                               )
                             )
                           );

      //-----------------------------------------------------------------------
      // Send it in as an Sh-Update request, and make sure it succeeded.
      //-----------------------------------------------------------------------
      shInstance.shUpdate(dNHolder.value,
                          0,
                          userData,
                          utilities.ORIGIN_HOST,
                          resultCodeHolder,
                          extendedResultHolder);

      utilities.checkResultCode(resultCodeHolder.value,
                                extendedResultHolder.value,
                                userDataHolder.value);

      System.out.println("Subscriber successfully created.");

      //-----------------------------------------------------------------------
      // Send an ShPull to get the new subscriber's alarm state.  Extract and
      // print the alarm state.
      //-----------------------------------------------------------------------
      shInstance.shPull(dNHolder.value,
                        0,
                        "Meta_Subscriber_Alarms",
                        utilities.ORIGIN_HOST,
                        resultCodeHolder,
                        extendedResultHolder,
                        userDataHolder);

      utilities.checkResultCode(resultCodeHolder.value,
                                extendedResultHolder.value,
                                userDataHolder.value);

      TMeta_Subscriber_Alarms alarms = userDataHolder.value
                                                  .getShData()
                                                  .getRepositoryData()
                                                  .getServiceData()
                                                  .getMetaSwitchData()
                                                  .getMeta_Subscriber_Alarms();

      System.out.println("Alarm state: \"" + alarms.getAlarmState() + "\"");
    }
    catch (MetaSwitchShInterfaceException e)
    {
      System.err.println(e.getMessage());
      System.err.println(USAGE);
    }
    catch (org.apache.axis.AxisFault e)
    {
      System.err.println("Problem connecting to MetaView Server: " + e);
      System.err.println(USAGE);
    }
    catch (javax.xml.rpc.ServiceException e)
    {
      System.err.println("Could not connect to Sh service");
      System.err.println(USAGE);
    }
    catch (Exception e)
    {
      System.err.println("Unexpected error \"" + e
                         + "\" in retrieving data");
      e.printStackTrace(System.err);
      System.err.println(USAGE);
    }
  }

  /**
   * Parse the command line arguments and extract the necessary information.
   * See the associated CreateSubscriber.bat script for parameter details.
   *
   * @returns          Information about the subscriber to be created.
   *
   * @param args        IN  The arguments provided at the command line.
   * @param emsAddress
   *                    OUT The URL to which to send SOAP messages (optional).
   * @param dN          OUT The directory number to update.
   *
   * @exception WrongParametersException
   */
  private static SubscriberInfo getParameters(String[] args,
                                              StringHolder emsAddress,
                                              StringHolder dN)
    throws WrongParametersException
  {
    Parameter emsAddressParameter = new Parameter(null);
    Parameter dNParameter = new Parameter(null);

    SubscriberInfo fields = new SubscriberInfo();
    String currentArg = "";
    for (String arg : args)
    {
      //-----------------------------------------------------------------------
      // Parse each parameter one by one (ignores anything before the first
      // flag).
      //-----------------------------------------------------------------------
      if (arg.startsWith("-"))
      {
        currentArg = arg.toLowerCase();
      }
      else
      {
        if (currentArg.equals("-ems"))
        {
          emsAddressParameter.append(arg);
        }
        else if (currentArg.equals("-dn"))
        {
          dNParameter.append(arg);
        }
        else if (currentArg.equals("-metaswitch"))
        {
          fields.metaSwitchName.append(arg);
        }
        else if(currentArg.equals("-businessgroup"))
        {
          fields.businessGroupName.append(arg);
        }
        else if(currentArg.equals("-subscribergroup"))
        {
          fields.subscriberGroup.append(arg);
        }
        else if(currentArg.equals("-profile"))
        {
          fields.persistentProfile.append(arg);
        }
        else if(currentArg.equals("-username"))
        {
          fields.sipUserName.append(arg);
        }
        else if(currentArg.equals("-domain"))
        {
          fields.sipDomainName.append(arg);
        }
        else if(currentArg.equals("-password"))
        {
          fields.sipPassword.append(arg);
        }
        else
        {
          throw new WrongParametersException("Unrecognised argument: " +
                                             currentArg);
        }
      }
    }

    if (emsAddressParameter.toString() == null)
    {
      emsAddress.value = null;
    }
    else
    {
      emsAddress.value = "http://" + emsAddressParameter.toString() +
                         ":8080/services/ShService";
    }

    if (dNParameter.toString() == null)
    {
      throw new WrongParametersException("No directory number was provided");
    }
    else
    {
      dN.value = dNParameter.toString();
    }

    return fields;
  }

  //---------------------------------------------------------------------------
  // INNER CLASS: SubscriberInfo
  //
  // Holds information about the subscriber to be created.
  //---------------------------------------------------------------------------
  static class SubscriberInfo
  {
    Parameter metaSwitchName = new Parameter(null);
    Parameter businessGroupName = new Parameter(null);
    Parameter subscriberGroup = new Parameter(null);
    Parameter persistentProfile = new Parameter("None");
    Parameter sipUserName = new Parameter(null);
    Parameter sipDomainName = new Parameter(null);
    Parameter sipPassword = new Parameter(null);
  }
}
